import  InitialiseData from './initialise-data'
import DesignViewGrid from './design-grid'
import  _ from 'lodash'
export default class DesignView {
    errorMessage1 = 'unable to find design view container in design-view.js';
    errorMessage2 = 'unable to find application in design-view.js';
   _$parent_el = [];
   options = [];
   application = [];
   jsPlumbInstance = null;
  constructor(options, application, jsPlumbInstance){
    var errorMessage1 = 'unable to find design view container in design-view.js';
    var errorMessage2 = 'unable to find application in design-view.js';

    this.options = options;
    this.application = application;
    this.jsPlumbInstance = jsPlumbInstance;
  }

  setRawExtensions(rawExtensions) {
    this.rawExtensions = rawExtensions;
  }

  getRawExtensions() {
    return this.rawExtensions;
  }

  /**
   * @function Renders tool palette in the design container
   */
  renderToolPalette() {
    var errMsg = '';
    var toolPaletteContainer =
      this._$parent_el.find(_.get(this.options, 'design_view.tool_palette.container')).get(0);
    if (!toolPaletteContainer) {
      errMsg = 'unable to find tool palette container with selector: '
        + _.get(this.options, 'design_view.tool_palette.container');
      throw errMsg;
    }
    var toolPaletteOpts = _.clone(_.get(this.options, 'design_view.tool_palette'));
    if (!toolPaletteOpts) {
      errMsg = 'unable to find tool palette with selector: '
        + _.get(this.options, 'design_view.tool_palette');
      throw errMsg;
    }
    toolPaletteOpts.container = toolPaletteContainer;
    this.toolPalette = new ToolPalette(toolPaletteOpts);
    this.toolPalette.render();
  };

  /**
   * @function Renders design view in the design container
   * @param configurationJSON Siddhi application content JSON
   */
  renderDesignGrid(configurationJSON) {
    var self = this;
    var initialiseData = new InitialiseData(self._$parent_el, self.application);
    initialiseData.setRawExtension(self.rawExtensions);
    this.configurationData = initialiseData.initialiseSiddhiAppData(configurationJSON);
    var designViewGridOpts = {};
    _.set(designViewGridOpts, 'container', this.designViewGridContainer);
    _.set(designViewGridOpts, 'configurationData', this.configurationData);
    _.set(designViewGridOpts, 'application', this.application);
    _.set(designViewGridOpts, 'jsPlumbInstance', this.jsPlumbInstance);
    this.designViewGrid = new DesignViewGrid(designViewGridOpts);
    this.designViewGrid.render();
  };

  setHashCode(hashCode) {
    this.renderedAppContentHashCode = hashCode;
  }

  getHashCode() {
    return this.renderedAppContentHashCode;
  }

  autoAlign() {
    if (!_.isUndefined(this.designViewGrid)) {
      this.designViewGrid.autoAlignElements();
    }
  };

  getConfigurationData() {
    return this.configurationData;
  };

  setConfigurationData(configurationData) {
    this.configurationData = configurationData;
  };

  emptyDesignViewGridContainer() {
    var errMsg = '';
    this.designViewGridContainer = this._$parent_el.find(_.get(this.options, 'design_view.grid_container'));
    if (!this.designViewGridContainer.length > 0) {
      errMsg = 'unable to find design view grid container with selector: '
        + _.get(this.options, 'design_view.grid_container');
      throw errMsg;
    }

    // reset the jsPlumb common instance
    if (this.jsPlumbInstance !== undefined) {
      this.jsPlumbInstance.clear();
      this.jsPlumbInstance.reset();
    }
    // remove any child nodes from designViewGridContainer if exists
    this.designViewGridContainer.empty();
  };

  showToolPalette() {
    if (this.toolPalette !== undefined) {
      this.toolPalette.showToolPalette();
    }
  };

  hideToolPalette() {
    if (this.toolPalette !== undefined) {
      this.toolPalette.hideToolPalette();
    }
  };

  /**
   * @function Renders design view in the design container
   * @param configurationJSON JSON which needs to be validated
   * @return {boolean} return whether the json is valid or not
   */
  validateJSONBeforeSendingToBackend(configurationJSON) {
    var self = this;
    var jsonValidator = new JSONValidator();
    return jsonValidator.validate(configurationJSON, self.jsPlumbInstance);
  };

  getDesign(code) {
    var self = this;
    var result = {};
    // Remove Single Line Comments
    var regexStr = code.replace(/--.*/g, '');
    // Remove Multi-line Comments
    regexStr = regexStr.replace(/\/\*(.|\s)*?\*\//g, '');
    var regex = /^\s*@\s*app\s*:\s*name\s*\(\s*["|'](.*)["|']\s*\)\s*@\s*app\s*:\s*description\s*\(\s*["|'](.*)["|']\s*\)\s*$/gi;
    var match = regex.exec(regexStr);

    // check whether Siddhi app is in initial mode(initial Siddhi app template) and if yes then go to the
    // design view with the no content
    if (match !== null) {
      var defaultResponse = {
        "siddhiAppConfig": {
          "siddhiAppName": match[1],
          "siddhiAppDescription": match[2],
          "appAnnotationList": [],
          "streamList": [],
          "tableList": [],
          "windowList": [],
          "triggerList": [],
          "aggregationList": [],
          "functionList": [],
          "partitionList": [],
          "sourceList": [],
          "sinkList": [],
          "queryLists": {
            "WINDOW_FILTER_PROJECTION": [],
            "PATTERN": [],
            "SEQUENCE": [],
            "JOIN": []
          },
          "finalElementCount": 0
        },
        "edgeList": []
      };
      var defaultString = JSON.stringify(defaultResponse);
      result = {
        status: "success",
        responseString: defaultString
      };
    } else {
      self.codeToDesignURL = window.location.protocol + "//" + window.location.host + "/editor/design-view";
      $.ajax({
        type: "POST",
        url: self.codeToDesignURL,
        data: btoa(unescape(encodeURIComponent(code))),
        async: false,
        success: function (response) {
          result = {status: "success", responseString: self.options.application.utils.
            b64DecodeUnicode(response)};
        },
        error: function (error) {
          if (error.responseText) {
            result = {status: "fail", errorMessage: error.responseText};
          } else {
            result = {status: "fail", errorMessage: "Error Occurred while processing your request"};
          }
        }
      });
    }
    return result;
  };

  getCode(designViewJSON) {
    var self = this;
    var result = {};
    self.designToCodeURL = window.location.protocol + "//" + window.location.host + "/editor/code-view";
    $.ajax({
      type: "POST",
      url: self.designToCodeURL,
      data: btoa(unescape(encodeURIComponent(designViewJSON))),//window.btoa(designViewJSON),
      async: false,
      success: function (response) {
        result = {status: "success", responseString: self.options.application.utils.
          b64DecodeUnicode(response)};
      },
      error: function (error) {
        if (error.responseText) {
          result = {status: "fail", errorMessage: error.responseText};
        } else {
          result = {status: "fail", errorMessage: "Error Occurred while processing your request"};
        }
      }
    });
    return result;
  };
}
